﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Model;
using Persistence;

namespace Persistence
{
    /// <summary>
    /// UnitWork é um padrão de projeto que permite trabalhar 
    /// com vários repositórios compartilhando um mesmo contexto
    /// transacional
    /// </summary>
    public class UnitOfWork : IDisposable, IUnitOfWork
    {
        private itaservicosbdEntities _context;
        private IRepositorioGenerico<tb_cliente> _repCliente;
        private IRepositorioGenerico<tb_prestador_servico> _repPrestadorServico;
        private IRepositorioGenerico<tb_servico> _repServico;
        private IRepositorioGenerico<tb_especialidade> _repEspecialidade;
        private IRepositorioGenerico<tb_prestador> _repPrestador;
        private IRepositorioGenerico<tb_solicitacao_servico> _repSolicitacaoServico;
        private IRepositorioGenerico<tb_avaliacao> _repAvaliacao;
        private IRepositorioGenerico<tb_servico_especialidade_temp> _repTemp;

        /// <summary>
        /// Construtor cria contexto transacional
        /// </summary>
        public UnitOfWork()
        {
            _context = new Model.itaservicosbdEntities();
        }

        #region IUnitOfWork Members

        /// <summary>
        /// Repositório para manipular dados persistidos de Pessoas
        /// </summary>
        public IRepositorioGenerico<tb_cliente> RepositorioCliente
        {
            get
            {
                if (_repCliente == null)
                {
                    _repCliente = new RepositorioGenerico<tb_cliente>(_context);
                }

                return _repCliente;
            }
        }

        /// <summary>
        /// Repositório para manipular dados persistidos de pessoa_serviço
        /// </summary>
        public IRepositorioGenerico<tb_prestador_servico> RepositorioPrestadorServico
        {
            get
            {
                if (_repPrestadorServico == null)
                {
                    _repPrestadorServico = new RepositorioGenerico<tb_prestador_servico>(_context);
                }
                return _repPrestadorServico;
            }
        }

        /// <summary>
        /// Repositório para manipular dados persistidos de Serviços
        /// </summary>
        public IRepositorioGenerico<tb_servico> RepositorioServico
        {
            get
            {
                if (_repServico == null)
                {
                    _repServico = new RepositorioGenerico<tb_servico>(_context);
                }
                return _repServico;
            }
        }

        public IRepositorioGenerico<tb_especialidade> RepositorioEspecialidade
        {
            get
            {
                if (_repEspecialidade == null)
                {
                    _repEspecialidade = new RepositorioGenerico<tb_especialidade>(_context);
                }
                return _repEspecialidade;
            }
        }

        public IRepositorioGenerico<tb_prestador> RepositorioPrestador
        {
            get
            {
                if (_repPrestador == null)
                {
                    _repPrestador = new RepositorioGenerico<tb_prestador>(_context);
                }
                return _repPrestador;
            }
        }

        public IRepositorioGenerico<tb_solicitacao_servico> RepositorioSolicitacaoServico
        {
            get
            {
                if (_repSolicitacaoServico == null)
                {
                    _repSolicitacaoServico = new RepositorioGenerico<tb_solicitacao_servico>(_context);
                }
                return _repSolicitacaoServico;
            }
        }

        public IRepositorioGenerico<tb_avaliacao> RepositorioAvaliacao
        {
            get
            {
                if (_repAvaliacao == null)
                {
                    _repAvaliacao = new RepositorioGenerico<tb_avaliacao>(_context);
                }
                return _repAvaliacao;
            }
        }

        public IRepositorioGenerico<tb_servico_especialidade_temp> RepositorioTemp
        {
            get
            {
                if (_repTemp == null)
                {
                    _repTemp = new RepositorioGenerico<tb_servico_especialidade_temp>(_context);
                }
                return _repTemp;
            }
        }

        /// <summary>
        /// Salva todas as mudanças realizadas no contexto
        /// quando o contexto não for compartilhado
        /// </summary>
        public void Commit(bool shared)
        {
            if (!shared)
                _context.SaveChanges();
        }

        #endregion

        private bool disposed = false;
        /// <summary>
        /// Retira da memória um determinado contexto
        /// </summary>
        /// <param name="disposing"></param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    _context.Dispose();
                }
            }
            this.disposed = true;
        }

        /// <summary>
        /// Limpa contexto da memória
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }
}
